Python os.environ.get() return None

为这个问题痛苦了很久!所以就决定把本该放在 Wiki 上的东西放这了!起因是明明设置了环境变量,却不能在 python 文件中获取。

问题描述

非常诡异的一件事
Jupter 和 python shell 都能运行的代码:

1
2
3
4
>>> from nltk.parse.stanford import StanfordParser
>>> parser=StanfordParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
>>> print list(parser.raw_parse("the quick brown fox jumps over the lazy dog"))
[Tree('ROOT', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['quick']), Tree('JJ', ['brown']), Tree('NN', ['fox'])]), Tree('NP', [Tree('NP', [Tree('NNS', ['jumps'])]), Tree('PP', [Tree('IN', ['over']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['lazy']), Tree('NN', ['dog'])])])])])])]

运行 py 文件就不行

1
2
3
4
5
6
from nltk.parse.stanford import StanfordParser
def getParserTree(line):
parser=StanfordParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
print list(parser.raw_parse(line))
getParserTree("the quick brown fox jumps over the lazy dog")

Error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Traceback (most recent call last):
File "Helper.py", line 70, in <module>
getParserTree(doc1)
File "Helper.py", line 55, in getParserTree
parser=StanfordParser(model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
File "/Library/Python/2.7/site-packages/nltk/parse/stanford.py", line 51, in __init__
key=lambda model_name: re.match(self._JAR, model_name)
File "/Library/Python/2.7/site-packages/nltk/internals.py", line 714, in find_jar_iter
raise LookupError('\n\n%s\n%s\n%s' % (div, msg, div))
LookupError:
===========================================================================
NLTK was unable to find stanford-parser\.jar! Set the CLASSPATH
environment variable.
For more information, on stanford-parser\.jar, see:
<http://nlp.stanford.edu/software/lex-parser.shtml>
===========================================================================

问题探索

来看一下环境变量,同样诡异的事就发生了,用 jupter 或 python shell 运行下面的代码,可以得到环境变量路径

1
2
3
>>> import os
>>> os.environ.get('CLASSPATH')
/Users/sure/stanford-tools//stanford-postagger-full-2015-04-20/stanford-postagger.jar:/Users/sure/stanford-tools//stanford-ner-2015-04-20/stanford-ner.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar

然而放到 py 文件里,就只能 output 出一个 None

为啥!明明设置好了环境变量!看 ~/.bash_profile

1
2
3
4
export STANFORDTOOLSDIR=/Users/sure/stanford-tools/
export CLASSPATH=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/stanford-postagger.jar:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/stanford-ner.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar
export STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/models:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/classifiers

索性一个简单粗暴的方法是直接在 py 文件里,StanfordParser 传进绝对地址参数,第一个参数是 path/to/jar,第二个参数是 path/to/module,然后就 可以运行文件了。

1
2
3
parser = StanfordParser('/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser.jar', '/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar',model_path="edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz")
print list(parser.raw_parse("the quick brown fox jumps over the lazy dog"))

然而想一想,我们要用 Stanford PoS tagging,要用 NER,要用 parser,还要用 dependency parser,那得多麻烦!而且作为一个 team,share code,每个人的路径都不一样。。。

有两个解决方案,一是把对应的 jar 包,model 之类的所有东西放进当前目录下,然后在 py 文件里 get 当前目录,再进行拼接,传入参数;二是单独设置一个配置文件,每个人都配好各自的环境,在 py 文件里调用配置文件,这两种方法都可以解决个人路径不一样的问题。

然而,为什么还是这么麻烦。为什么 get 不到环境变量!

问题解决

来看一下 os.environ 这个函数,才发现 os.environ 保存的是 python 运行的当前 shell 中的环境变量。于是就想到了:我们根本没有在当前 shell 中 mark & export varible 好不好!所以:

1
2
3
4
5
6
7
8
$ STANFORDTOOLSDIR=/Users/sure/stanford-tools/
$ CLASSPATH=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/stanford-postagger.jar:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/stanford-ner.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser.jar:$STANFORDTOOLSDIR/stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar
$ STANFORD_MODELS=$STANFORDTOOLSDIR/stanford-postagger-full-2015-04-20/models:$STANFORDTOOLSDIR/stanford-ner-2015-04-20/classifiers
$ export STANFORDTOOLSDIR
$ export CLASSPATH
$ export STANFORD_MODELS
$ python2.7 -c 'import os;print os.environ.get("CLASSPATH")'
/Users/sure/stanford-tools//stanford-postagger-full-2015-04-20/stanford-postagger.jar:/Users/sure/stanford-tools//stanford-ner-2015-04-20/stanford-ner.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar

Done!

1
2
3
$ python2.7 Helper.py
/Users/sure/stanford-tools//stanford-postagger-full-2015-04-20/stanford-postagger.jar:/Users/sure/stanford-tools//stanford-ner-2015-04-20/stanford-ner.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser.jar:/Users/sure/stanford-tools//stanford-parser-full-2015-04-20/stanford-parser-3.5.2-models.jar
[Tree('ROOT', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['quick']), Tree('JJ', ['brown']), Tree('NN', ['fox'])]), Tree('NP', [Tree('NP', [Tree('NNS', ['jumps'])]), Tree('PP', [Tree('IN', ['over']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['lazy']), Tree('NN', ['dog'])])])])])])]

徐阿衡 wechat
欢迎关注:徐阿衡的微信公众号
客官,打个赏呗~